package com.jb.faces.el;

import com.jb.framework.util.PropUtil;
import com.jb.web.application.StringUtil;
import com.jb.web.application.SystemUtil;
import com.jb.web.bean.FormField;
import com.jb.web.context.WebContext;

import java.lang.reflect.Method;

import java.util.Date;

import javax.servlet.jsp.el.FunctionMapper;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


class JBFunctionMapper implements FunctionMapper {
    protected static Log log = LogFactory.getLog(JBFunctionMapper.class.getName());
  
    private WebContext context;

    public JBFunctionMapper(WebContext pCtx) {
        context = pCtx;
    }

    public Method resolveFunction(String prefix, String localName) {
        if (log.isDebugEnabled()) {
            log.debug("Resolve Function " + prefix + ":" + localName);
        }

        if ("system".equals(prefix)) {
            if ("showDialogBox".equals(localName)) {
                try {
                    return SystemUtil.class.getMethod("showDialogBox",
                        new Class[] { WebContext.class, String.class, String.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function" + e.getMessage());
                    }

                    return null;
                }
            }
        }

        if ("string".equals(prefix)) {
            if ("length".equals(localName)) {
                try {
                    return StringUtil.class.getMethod("length",
                        new Class[] {String.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function" + e.getMessage());
                    }
                    return null;
                }
            }
            if ("isNumber".equals(localName)) {
                try {
                    return StringUtil.class.getMethod("isNumber",
                        new Class[] {String.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function" + e.getMessage());
                    }
                    return null;
                }
            }
            
            if("isFormatValid".equals(localName)) {
                try {
                    return StringUtil.class.getMethod("isFormatValid",
                        new Class[] {String.class, String.class});
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function" + e.getMessage());
                    }
                    return null;
                }
            }
            if("validate".equals(localName)) {
                try {
                    return StringUtil.class.getMethod("validate",
                        new Class[] {FormField.class, String.class});
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function" + e.getMessage());
                    }
                    return null;
                }
            }
            
        }
        
        if ("jb".equals(prefix)) {
            if ("scopeAttr".equals(localName)) {
                try {
                    return SystemUtil.class.getMethod("setScopeAttr",
                        new Class[] { Object.class, Object.class, Object.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function :" + prefix + ":"+localName);
                    }
                    return null;
                }
            }

            if ("access".equals(localName)) {
                try {
                    return SystemUtil.class.getMethod("getAccess", new Class[] { WebContext.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function :" + prefix + ":"+localName);
                    }
                    return null;
                }
            }

            if ("year".equals(localName)) {
                try {
                    return CalendarUtil.class.getMethod("getYear", new Class[] { Date.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function :" + prefix + ":"+localName);
                    }

                    return null;
                }
            }

            if ("raceTime".equals(localName)) {
                try {
                    return CalendarUtil.class.getMethod("getRaceTime", new Class[] { Long.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function :" + prefix + ":"+localName);
                    }

                    return null;
                }
            }

            if ("month".equals(localName)) {
                try {
                    return CalendarUtil.class.getMethod("getMonth", new Class[] { Date.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function :" + prefix + ":"+localName);
                    }

                    return null;
                }
            }

            if ("invoke2".equals(localName)) {
                try {
                    return PropUtil.class.getMethod("invoke2", new Class[] { Object.class, String.class, Object.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function :" + prefix + ":"+localName);
                    }

                    return null;
                }
            }
            if ("assign".equals(localName)) {
                try {
                    return PropUtil.class.getMethod("setProperty",
                        new Class[] { Object.class, String.class, Object.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function :" + prefix + ":"+localName);
                    }

                    return null;
                }
            }

            if ("authorized".equals(localName)) {
                try {
                    return SystemUtil.class.getMethod("isAuthorized",
                        new Class[] { com.jb.web.session.Session.class, Object.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function :" + prefix + ":"+localName);
                    }

                    return null;
                }
            }

            if ("validate".equals(localName)) {
                try {
                    return AttributeEvaluator.class.getMethod("validate", new Class[] { Boolean.class, String.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function :" + prefix + ":"+localName);
                    }

                    return null;
                }
            }

            if ("invoke".equals(localName)) {
                try {
                    return com.jb.framework.util.PropUtil.class.getMethod("invoke",
                        new Class[] { Object.class, String.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function :" + prefix + ":"+localName);
                    }

                    return null;
                }
            }

            if ("invokeStatic".equals(localName)) {
                try {
                    return com.jb.framework.util.PropUtil.class.getMethod("invoke",
                        new Class[] { Object.class, String.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function :" + prefix + ":"+localName);
                    }

                    return null;
                }
            }
        }
        if ("security".equals(prefix)) {

            if ("access".equals(localName)) {
                try {
                    return SystemUtil.class.getMethod("getAccess", new Class[] { WebContext.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function :" + prefix + ":"+localName);
                    }

                    return null;
                }
            }

            if ("authorized".equals(localName)) {
                try {
                    return SystemUtil.class.getMethod("isAuthorized",
                        new Class[] { com.jb.web.session.Session.class, Object.class });
                } catch (NoSuchMethodException e) {
                    if (context != null) {
                        context.addErrorMessage(this, "Can not resolve function :" + prefix + ":"+localName);
                    }

                    return null;
                }
            }
        }
        return null;
    }
}
